{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#! -*- coding: utf-8 -*-\n",
    "\"\"\"\n",
    "Author: ZhenYuSha\n",
    "Create Time: 2019-1-14\n",
    "Info: Websocket 的使用示例\n",
    "\"\"\"\n",
    "import asyncio\n",
    "import websockets\n",
    "\n",
    "import nest_asyncio\n",
    "nest_asyncio.apply()\n",
    "\n",
    "websocket_users = set()\n",
    "\n",
    "\n",
    "# 检测客户端权限，用户名密码通过才能退出循环\n",
    "async def check_user_permit(websocket):\n",
    "    print(\"new websocket_users:\", websocket)\n",
    "    websocket_users.add(websocket)\n",
    "    print(\"websocket_users list:\", websocket_users)\n",
    "    while True:\n",
    "        recv_str = await websocket.recv()\n",
    "        cred_dict = recv_str.split(\":\")\n",
    "        if cred_dict[0] == \"admin\" and cred_dict[1] == \"123456\":\n",
    "            response_str = \"Congratulation, you have connect with server...\"\n",
    "            await websocket.send(response_str)\n",
    "            print(\"Password is ok...\")\n",
    "            return True\n",
    "        else:\n",
    "            response_str = \"Sorry, please input the username or password...\"\n",
    "            print(\"Password is wrong...\")\n",
    "            await websocket.send(response_str)\n",
    "\n",
    "\n",
    "# 接收客户端消息并处理，这里只是简单把客户端发来的返回回去\n",
    "async def recv_user_msg(websocket):\n",
    "    while True:\n",
    "        recv_text = await websocket.recv()\n",
    "        print(\"recv_text:\", websocket.pong, recv_text)\n",
    "        response_text = f\"Server return: {recv_text}\"\n",
    "        print(\"response_text:\", response_text)\n",
    "        await websocket.send(response_text)\n",
    "\n",
    "\n",
    "# 服务器端主逻辑\n",
    "async def run(websocket, path):\n",
    "    while True:\n",
    "        print(path)\n",
    "        try:\n",
    "            await recv_user_msg(websocket)\n",
    "        except websockets.ConnectionClosed:\n",
    "            print(\"ConnectionClosed...\", path)    # 链接断开\n",
    "            print(\"websocket_users old:\", websocket_users)\n",
    "            websocket_users.remove(websocket)\n",
    "            print(\"websocket_users new:\", websocket_users)\n",
    "            break\n",
    "        except websockets.InvalidState:\n",
    "            print(\"InvalidState...\")    # 无效状态\n",
    "            break\n",
    "        except Exception as e:\n",
    "            print(\"Exception:\", e)\n",
    "\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    print(\"127.0.0.1:8181 websocket...\")\n",
    "    asyncio.get_event_loop().run_until_complete(websockets.serve(run, \"127.0.0.1\", 8181))\n",
    "    asyncio.get_event_loop().run_forever()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import asyncio\n",
    "import websockets\n",
    " \n",
    "IP_ADDR = \"127.0.0.1\"\n",
    "IP_PORT = \"8888\"\n",
    " \n",
    "# 握手，通过接收hello，发送\"123\"来进行双方的握手。\n",
    "async def serverHands(websocket):\n",
    "    while True:\n",
    "        recv_text = await websocket.recv()\n",
    "        print(\"recv_text=\" + recv_text)\n",
    "        if recv_text == \"hello\":\n",
    "            print(\"connected success\")\n",
    "            await websocket.send(\"123\")\n",
    "            return True\n",
    "        else:\n",
    "            await websocket.send(\"connected fail\")\n",
    " \n",
    " \n",
    "# 接收从客户端发来的消息并处理，再返给客户端ok\n",
    "async def serverRecv(websocket):\n",
    "    while True:\n",
    "        recv_text = await websocket.recv()\n",
    "        print(\"recv:\", recv_text)\n",
    "        await websocket.send(\"ok!!!\")\n",
    " \n",
    " \n",
    "# 握手并且接收数据\n",
    "async def serverRun(websocket, path):\n",
    "    print(path)\n",
    "    await serverHands(websocket)\n",
    " \n",
    "    await serverRecv(websocket)\n",
    " \n",
    "#main function\n",
    "if __name__ == '__main__':\n",
    "    print(\"======server main begin======\")\n",
    "    server = websockets.serve(serverRun, IP_ADDR, IP_PORT)\n",
    "    asyncio.get_event_loop().run_until_complete(server)\n",
    "    asyncio.get_event_loop().run_forever()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import asyncio\n",
    "import websockets\n",
    "\n",
    "async def echo(websocket, path):\n",
    "    #fetch msg\n",
    "    async for message in websocket:\n",
    "        print(\"got a message:{}\".format(message))\n",
    "        await websocket.send(message)\n",
    "\n",
    "async def main():\n",
    "    # start a websocket server\n",
    "    async with websockets.serve(echo, \"localhost\", 8765):\n",
    "        await asyncio.Future()  # run forever\n",
    "\n",
    "asyncio.run(main())"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "0d97df724f9992bec51a1ba2c335179ff7e7085e5d5d4df7f317912701d4af90"
  },
  "kernelspec": {
   "display_name": "Python 3.7.3 64-bit (system)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
